#include "base.h"


bool	NoWindow	= false;
bool	Result		= false;
int		ref_Frame		=0;
int		ref_Message		=0;
int		ref_Exit		=0;
int		ref_FocusLost	=0;
int		ref_FocusGain	=0;

bool Frame()
{
	EnterCriticalSection(&g_cs);
	lua_rawgeti(L, LUA_REGISTRYINDEX, ref_Frame);
 	lua_call(L,0,1);
 	Result = lua_toboolean(L,-1)? true : false;
 	lua_pop(L,1);
	LeaveCriticalSection(&g_cs);
	return Result;
}
bool Message(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	if (NoWindow && uMsg == WM_STYLECHANGING && wParam == GWL_STYLE) { 
		STYLESTRUCT *StyleStruct = (STYLESTRUCT*)lParam; 
		StyleStruct->styleNew = WS_POPUP|WS_VISIBLE; 
	} 
	EnterCriticalSection(&g_cs);
	lua_rawgeti(L, LUA_REGISTRYINDEX, ref_Message);
	lua_pushnumber(L,(long)hwnd);
	lua_pushnumber(L,uMsg);
	lua_pushnumber(L,wParam);
	lua_pushnumber(L,lParam);
	lua_call(L,4,1);
	Result = lua_toboolean(L,-1)? true : false;
	lua_pop(L,1);
	LeaveCriticalSection(&g_cs);
	return Result;
}
bool Exit()
{
	EnterCriticalSection(&g_cs);
	lua_rawgeti(L, LUA_REGISTRYINDEX, ref_Exit);
	lua_call(L,0,1);
	Result = lua_toboolean(L,-1)? true : false;
	lua_pop(L,1);
	LeaveCriticalSection(&g_cs);
	return Result;
}
bool FocusLost()
{
	EnterCriticalSection(&g_cs);
	lua_rawgeti(L, LUA_REGISTRYINDEX, ref_FocusLost);
	lua_call(L,0,1);
	Result = lua_toboolean(L,-1)? true : false;
	lua_pop(L,1);
	LeaveCriticalSection(&g_cs);
	return Result;
}

bool FocusGain()
{
	EnterCriticalSection(&g_cs);
	lua_rawgeti(L, LUA_REGISTRYINDEX, ref_FocusGain);
	lua_call(L,0,1);
	Result = lua_toboolean(L,-1)? true : false;
	lua_pop(L,1);
	LeaveCriticalSection(&g_cs);
	return Result;
}
//System
bool		ggeBase::Engine_Create(){
	return gge::Engine_Create();
}
bool		ggeBase::System_Initiate(){
	IsInit = true;
	return gge::System_Initiate();
}
bool		ggeBase::System_Start(){
	return gge::System_Start();
}
void		ggeBase::Engine_Release(){
	return gge::Engine_Release();
}
void		ggeBase::System_SetStateChar(int state ,const char *value){
	gge::System_SetState(gge::GGE_STATE_CHAR(state),value);
}
void		ggeBase::System_SetStateInt(int state ,int value){
	gge::System_SetState(gge::GGE_STATE_INT(state),value);
}
void		ggeBase::System_SetStateBool(int state ,bool value){
	gge::System_SetState(gge::GGE_STATE_BOOL(state),value);
}
void		ggeBase::System_NoWindow(bool value){
	NoWindow = value;
}
void		ggeBase::System_SetStateFun(int state){
	switch(state)
	{ 
		case 0:gge::System_SetState(gge::GGE_FRAMEFUNC, Frame);
			ref_Frame = luaL_ref(L, LUA_REGISTRYINDEX);
			break;
		case 1:gge::System_SetState(gge::GGE_EXITFUNC, Exit);
			ref_Exit = luaL_ref(L, LUA_REGISTRYINDEX);
			break;
		case 2:gge::System_SetState(gge::GGE_FOCUSLOSTFUNC, FocusLost);
			ref_FocusLost = luaL_ref(L, LUA_REGISTRYINDEX);
			break;
		case 3:gge::System_SetState(gge::GGE_FOCUSGAINFUNC, FocusGain);
			ref_FocusGain = luaL_ref(L, LUA_REGISTRYINDEX);
			break;
		case 4:gge::System_SetState(gge::GGE_MESSAGEFUNC, Message);
			ref_Message = luaL_ref(L, LUA_REGISTRYINDEX);
			break;
	}
}
const char* ggeBase::System_GetStateChar(int state ){
	return gge::System_GetState(gge::GGE_STATE_CHAR(state));
}
int			ggeBase::System_GetStateInt(int state ){
	return gge::System_GetState(gge::GGE_STATE_INT(state));
}
bool		ggeBase::System_GetStateBool(int state){
	return gge::System_GetState(gge::GGE_STATE_BOOL(state));
}
int			ggeBase::System_GetStateHwnd(){
	return (int)gge::System_GetState(gge::GGE_STATE_SYS_VAL::GGE_HWND);
}
void		ggeBase::System_Log(const char *format){
	gge::System_Log(format);
}
bool		ggeBase::System_Launch(const char *url){
	return gge::System_Launch(url);
}
//Ini
void		ggeBase::Ini_SetFile(const char *v){
	gge::Ini_SetFile(v);
}
void		ggeBase::Ini_SetString(const char *section, const char *name, const char *value){
	gge::Ini_SetString(section,name,value);
}
const char* ggeBase::Ini_GetString(const char *section, const char *name, const char *value){
	return gge::Ini_GetString(section,name,value);
}
//Timer
float		ggeBase::Timer_GetTime(){
	return gge::Timer_GetTime ();
}
UINT		ggeBase::Timer_GetTick(){
	return gge::Timer_GetTick ();
}
float		ggeBase::Timer_GetDelta(){
	return gge::Timer_GetDelta ();
}
int			ggeBase::Timer_GetFPS(){
	return gge::Timer_GetFPS ();
}
//Random
void		ggeBase::Random_Seed(int seed){
	gge::Random_Seed (seed);
}
int			ggeBase::Random_Int(int min, int max){
	return gge::Random_Int (min,max);
}
float		ggeBase::Random_Float(float min, float max){
	return gge::Random_Float (min,max);
}
//Graph
void		ggeBase::Graph_Clear(UINT color){
	gge::Graph_Clear (color);
}
bool		ggeBase::Graph_BeginScene(UINT texture){
	return gge::Graph_BeginScene (texture?(gge::ggeTexture *)texture:0);
}
void		ggeBase::Graph_EndScene(){
	gge::Graph_EndScene ();
}
void		ggeBase::Graph_GetRenderTarget(UINT texture){
//	gge::Graph_GetRenderTarget ((gge::ggeTexture *)texture);
}
void		ggeBase::Graph_RenderLine(float x1, float y1, float x2, float y2, gge::gUInt color, float z){
	gge::Graph_RenderLine (x1,y1,x2,y2,color/*,z*/);
}
void		ggeBase::Graph_RenderQuad(float x1, float y1, float x2, float y2, gge::gUInt color, float z){
//	gge::Graph_RenderQuad (x1,y1,x2,y2,color,z);
}
void		ggeBase::Graph_SetClipping(int x, int y, int width, int height){
	gge::ggeClipRect r;
	r.x = x, r.y = y, r.width = width, r.height = height;
	gge::Graph_PushClipRect(r);
}
void		ggeBase::Graph_SetTransform(float x, float y, float dx, float dy, float rot, float hscale, float vscale){
//	gge::Graph_SetTransform (x,y,dx,dy,rot,hscale,vscale);
}
void		ggeBase::Graph_Snapshot(const char *filename,int format){
	gge::Graph_Snapshot (filename,gge::GGE_IMAGE_FORMAT(format));
}
void		ggeBase::Graph_RenderBatch(int primType, LuaTable vt, int primNum,UINT tex, int blend , bool bFilter){

	gge::ggeVertex* vertex = new gge::ggeVertex[primNum];
	for (int i = 0;i<primNum;i++)
	{
		LuaTable v = vt.get(i);
		vertex[i].x = v.get<float>("x");
		vertex[i].y = v.get<float>("y");
		vertex[i].z = v.get<float>("z");
		vertex[i].tx = v.get<float>("tx");
		vertex[i].ty = v.get<float>("ty");
		vertex[i].color = v.get<UINT>("color");
	}
	gge::Graph_RenderBatch(gge::PRIM_TYPE(primType),vertex,primNum,tex?(gge::ggeTexture*)tex:0,blend/*,bFilter*/);
	delete []vertex;
}
//Input

float ggeBase::Input_GetMousePosX(){
	return gge::Input_GetMousePosX ();
}
float ggeBase::Input_GetMousePosY(){
	return gge::Input_GetMousePosY ();
}
int ggeBase::Input_GetMouseWheel(){
	return gge::Input_GetMouseWheel ();
}
bool		ggeBase::Input_IsMouseOver(){
	return gge::Input_IsMouseOver ();
}
bool		ggeBase::Input_IsKeyPress(int key){
	return gge::Input_IsKeyPress (key);
}
bool		ggeBase::Input_IsKeyUp(int key){
	return gge::Input_IsKeyUp (key);
}
bool		ggeBase::Input_IsKeyDown(int key){
	return gge::Input_IsKeyDown (key);
}
bool		ggeBase::Input_IsMousePress(int key){
	return gge::Input_IsMousePress (key);
}
bool		ggeBase::Input_IsMouseUp(int key){
	return gge::Input_IsMouseUp (key);
}
bool		ggeBase::Input_IsMouseDown(int key){
	return gge::Input_IsMouseDown (key);
}
int			ggeBase::Input_GetKey(){
	return gge::Input_GetKey ();
}
const char * ggeBase::Input_GetChar(){
	return gge::Input_GetChar ();
}
//Video

bool		ggeBase::Video_LoadFromFile(const char *filename){
	return true; // gge::Video_LoadFromFile(filename);
}
void		ggeBase::Video_Play(){
//	gge::Video_Play ();
}
void		ggeBase::Video_Pause(){
//	gge::Video_Pause ();
}
void		ggeBase::Video_Stop(){
//	gge::Video_Stop ();
}
void		ggeBase::Video_Render(){
//	gge::Video_Render ();
}
void		ggeBase::Video_RenderEx(float x, float y, float width, float height){
//	gge::Video_RenderEx (x,y,width,height);
}
bool		ggeBase::Video_IsPlaying(){
	return true; // gge::Video_IsPlaying();
}
double		ggeBase::Video_GetPlayingTime(){
	return 0; // gge::Video_GetPlayingTime();
}
void		ggeBase::Video_SetVolume(int volume){
//	gge::Video_SetVolume (volume);
}

//Resource
ULONG		ggeBase::Resource_Load(const char *filename){
	return (int)gge::Resource_Load(filename);
}
const char *ggeBase::Resource_ToText(int res){
	return (const char*)res;
}
DWORD		ggeBase::Resource_GetSize(const char *filename){
	return gge::Resource_GetSize(filename);
}
bool		ggeBase::Resource_IsExist(const char *filename){
	return gge::Resource_IsExist(filename);
}
void		ggeBase::Resource_Free(ULONG res){
	gge::Resource_Free((const char*)res);
}
DWORD		ggeBase::Resource_LoadTo(const char *filename,ULONG buf,ULONG size){
	return gge::Resource_LoadTo(filename,(char*)buf,size);
}
bool		ggeBase::Resource_AttachPack(const char *filename, const char *password){
	return gge::Resource_AttachPack(filename,password);
}
void		ggeBase::Resource_RemovePack(const char *filename){
	gge::Resource_RemovePack(filename);
}
void		ggeBase::Resource_AddPath(const char *filename){
	gge::Resource_AddPath(filename);
}
const char*	ggeBase::Resource_GetPackFirstFileName(const char *filename){
	return NULL; // gge::Resource_GetPackFirstFileName(filename);
}
const char*	ggeBase::Resource_GetPackNextFileName(){
	return NULL; // gge::Resource_GetPackNextFileName();
}

int REG_GGE_Base(lua_State * L){

	const char* gname = "__ggeBase";

	ELuna::registerClass<ggeBase>(L, gname, ELuna::constructor<ggeBase>);

	ELuna::registerMethod<ggeBase>(L, "Engine_Create", &ggeBase::Engine_Create);
	ELuna::registerMethod<ggeBase>(L, "System_Initiate", &ggeBase::System_Initiate);
	//ELuna::registerMethod<ggeBase>(L, "System_Start", &ggeBase::System_Start);
	ELuna::registerMethod<ggeBase>(L, "Engine_Release", &ggeBase::Engine_Release);
	ELuna::registerMethod<ggeBase>(L, "System_SetStateChar", &ggeBase::System_SetStateChar);
	ELuna::registerMethod<ggeBase>(L, "System_SetStateInt", &ggeBase::System_SetStateInt);
	ELuna::registerMethod<ggeBase>(L, "System_SetStateBool", &ggeBase::System_SetStateBool);
	ELuna::registerMethod<ggeBase>(L, "System_SetStateFun", &ggeBase::System_SetStateFun);
	ELuna::registerMethod<ggeBase>(L, "System_NoWindow", &ggeBase::System_NoWindow);
	ELuna::registerMethod<ggeBase>(L, "System_GetStateHwnd", &ggeBase::System_GetStateHwnd);
	ELuna::registerMethod<ggeBase>(L, "System_GetStateInt", &ggeBase::System_GetStateInt);
	ELuna::registerMethod<ggeBase>(L, "System_GetStateBool", &ggeBase::System_GetStateBool);
	ELuna::registerMethod<ggeBase>(L, "System_GetStateChar", &ggeBase::System_GetStateChar);
	ELuna::registerMethod<ggeBase>(L, "System_Log", &ggeBase::System_Log);
	ELuna::registerMethod<ggeBase>(L, "System_Launch", &ggeBase::System_Launch);

	ELuna::registerMethod<ggeBase>(L, "Resource_Load", &ggeBase::Resource_Load);
	ELuna::registerMethod<ggeBase>(L, "Resource_ToText", &ggeBase::Resource_ToText);
	ELuna::registerMethod<ggeBase>(L, "Resource_GetSize", &ggeBase::Resource_GetSize);
	ELuna::registerMethod<ggeBase>(L, "Resource_IsExist", &ggeBase::Resource_IsExist);
	ELuna::registerMethod<ggeBase>(L, "Resource_Free", &ggeBase::Resource_Free);
	ELuna::registerMethod<ggeBase>(L, "Resource_LoadTo", &ggeBase::Resource_LoadTo);
	ELuna::registerMethod<ggeBase>(L, "Resource_AttachPack", &ggeBase::Resource_AttachPack);
	ELuna::registerMethod<ggeBase>(L, "Resource_RemovePack", &ggeBase::Resource_RemovePack);
	ELuna::registerMethod<ggeBase>(L, "Resource_AddPath", &ggeBase::Resource_AddPath);
	ELuna::registerMethod<ggeBase>(L, "Resource_GetPackFirstFileName", &ggeBase::Resource_GetPackFirstFileName);
	ELuna::registerMethod<ggeBase>(L, "Resource_GetPackNextFileName", &ggeBase::Resource_GetPackNextFileName);

	ELuna::registerMethod<ggeBase>(L, "Ini_SetFile", &ggeBase::Ini_SetFile);
	ELuna::registerMethod<ggeBase>(L, "Ini_SetString", &ggeBase::Ini_SetString);
	ELuna::registerMethod<ggeBase>(L, "Ini_GetString", &ggeBase::Ini_GetString);

	ELuna::registerMethod<ggeBase>(L, "Timer_GetTime", &ggeBase::Timer_GetTime);
	ELuna::registerMethod<ggeBase>(L, "Timer_GetTick", &ggeBase::Timer_GetTick);
	ELuna::registerMethod<ggeBase>(L, "Timer_GetDelta", &ggeBase::Timer_GetDelta);
	ELuna::registerMethod<ggeBase>(L, "Timer_GetFPS", &ggeBase::Timer_GetFPS);

	ELuna::registerMethod<ggeBase>(L, "Random_Seed", &ggeBase::Random_Seed);
	ELuna::registerMethod<ggeBase>(L, "Random_Int", &ggeBase::Random_Int);
	ELuna::registerMethod<ggeBase>(L, "Random_Float", &ggeBase::Random_Float);

	ELuna::registerMethod<ggeBase>(L, "Graph_Clear", &ggeBase::Graph_Clear);
	ELuna::registerMethod<ggeBase>(L, "Graph_BeginScene", &ggeBase::Graph_BeginScene);
	ELuna::registerMethod<ggeBase>(L, "Graph_EndScene", &ggeBase::Graph_EndScene);
	ELuna::registerMethod<ggeBase>(L, "Graph_GetRenderTarget", &ggeBase::Graph_GetRenderTarget);
	ELuna::registerMethod<ggeBase>(L, "Graph_RenderLine", &ggeBase::Graph_RenderLine);
	ELuna::registerMethod<ggeBase>(L, "Graph_RenderQuad", &ggeBase::Graph_RenderQuad);
	ELuna::registerMethod<ggeBase>(L, "Graph_SetClipping", &ggeBase::Graph_SetClipping);
	ELuna::registerMethod<ggeBase>(L, "Graph_SetTransform", &ggeBase::Graph_SetTransform);
	ELuna::registerMethod<ggeBase>(L, "Graph_Snapshot", &ggeBase::Graph_Snapshot);
	ELuna::registerMethod<ggeBase>(L, "Graph_RenderBatch", &ggeBase::Graph_RenderBatch);

	ELuna::registerMethod<ggeBase>(L, "Input_GetMousePosX", &ggeBase::Input_GetMousePosX);
	ELuna::registerMethod<ggeBase>(L, "Input_GetMousePosY", &ggeBase::Input_GetMousePosY);
	ELuna::registerMethod<ggeBase>(L, "Input_GetMouseWheel", &ggeBase::Input_GetMouseWheel);
	ELuna::registerMethod<ggeBase>(L, "Input_IsMouseOver", &ggeBase::Input_IsMouseOver);
	ELuna::registerMethod<ggeBase>(L, "Input_IsKeyPress", &ggeBase::Input_IsKeyPress);
	ELuna::registerMethod<ggeBase>(L, "Input_IsKeyUp", &ggeBase::Input_IsKeyUp);
	ELuna::registerMethod<ggeBase>(L, "Input_IsKeyDown", &ggeBase::Input_IsKeyDown);
	ELuna::registerMethod<ggeBase>(L, "Input_IsMousePress", &ggeBase::Input_IsMousePress);
	ELuna::registerMethod<ggeBase>(L, "Input_IsMouseUp", &ggeBase::Input_IsMouseUp);
	ELuna::registerMethod<ggeBase>(L, "Input_IsMouseDown", &ggeBase::Input_IsMouseDown);
	ELuna::registerMethod<ggeBase>(L, "Input_GetKey", &ggeBase::Input_GetKey);
	ELuna::registerMethod<ggeBase>(L, "Input_GetChar", &ggeBase::Input_GetChar);

	ELuna::registerMethod<ggeBase>(L, "Video_LoadFromFile", &ggeBase::Video_LoadFromFile);
	ELuna::registerMethod<ggeBase>(L, "Video_Play", &ggeBase::Video_Play);
	ELuna::registerMethod<ggeBase>(L, "Video_Render", &ggeBase::Video_Render);
	ELuna::registerMethod<ggeBase>(L, "Video_Pause", &ggeBase::Video_Pause);
	ELuna::registerMethod<ggeBase>(L, "Video_Stop", &ggeBase::Video_Stop);
	ELuna::registerMethod<ggeBase>(L, "Video_RenderEx", &ggeBase::Video_RenderEx);
	ELuna::registerMethod<ggeBase>(L, "Video_IsPlaying", &ggeBase::Video_IsPlaying);
	ELuna::registerMethod<ggeBase>(L, "Video_GetPlayingTime", &ggeBase::Video_GetPlayingTime);
	ELuna::registerMethod<ggeBase>(L, "Video_SetVolume", &ggeBase::Video_SetVolume);

	lua_getglobal(L, gname);
	lua_pushnil(L);
	lua_setglobal(L,gname);
	return 1;
}
